import numpy as np
import argparse
from fitting.curve_fitting import run_curve_fitting
from utils import calculate_average_error, plot_result, uniform_samples_with_noise, uniform_samples

# 定义标准函数
def sincos_function(x, c=1, d=1, e=1, f=1):
    x = np.array(x)
    return c * np.sin(d * x) + e * np.cos(f * x)

def main():
    # 设置命令行参数解析
    parser = argparse.ArgumentParser(description="Curve Fitting with Noisy Uniform Sampling")
    parser.add_argument('--interval', type=float, nargs=2, default=[-1, 1], help="fitting interval [a, b]")
    parser.add_argument('--num_samples', type=int, default=50, help="Number of sample points")
    parser.add_argument('--num_experiments', type=int, default=1000, help="Number of experimental points")
    parser.add_argument('--c', type=float, default=1, help="Parameter c in standard function")
    parser.add_argument('--d', type=float, default=2, help="Parameter d in standard function")
    parser.add_argument('--e', type=float, default=3, help="Parameter e in standard function")
    parser.add_argument('--f', type=float, default=4, help="Parameter f in standard function")
    parser.add_argument('--noise', type=float, default=0.01, help="Noise level for sample points")
    parser.add_argument('--intervals', type=int, nargs='+', default=None, help="List of interval divisions for piecewise fitting")
    
    args = parser.parse_args()
    
    # 提取参数
    interval = args.interval
    num_samples = args.num_samples
    num_experiments = args.num_experiments
    c, d, e, f = args.c, args.d, args.e, args.f
    noise_level = args.noise
    intervals = args.intervals

    # 打印实验设置
    print(f"Experiment Setup:")
    print(f"Interval: {interval}")
    print(f"Number of Samples: {num_samples}")
    print(f"Number of Experiments: {num_experiments}")
    print(f"Noise Level: {noise_level}")
    print(f"Standard Function Parameters (c, d, e, f): ({c}, {d}, {e}, {f})")
    print(f"Interval Divisions: {intervals if intervals else 'Global Fit'}")

    # 生成样本点
    x_samples, y_samples_noisy = uniform_samples_with_noise(interval, lambda x: sincos_function(x, c, d, e, f), num_samples, noise_level)
    
    # 生成实验数据
    x_experiment = uniform_samples(interval[0], interval[1], num_experiments)
    y_true = sincos_function(x_experiment, c, d, e, f)

    print("Starting curve fitting...")

    # 调用曲线拟合函数
    fitting_results = run_curve_fitting(
         x_samples,
         y_samples_noisy,
         intervals=intervals,  
         num_experiments=num_experiments,
         max_degree=4
    )

    # 计算和输出平均误差
    for interval, results in fitting_results.items():
        print(f"Interval: {interval}")
        errors = {}
        for result in results:
            degree = result['degree']
            y_interp = result['y_fit']
            average_error = calculate_average_error(y_true, y_interp)
            errors[f"Degree {degree}"] = average_error
        
        print("Average Errors:")
        for method, error in errors.items():
            print(f"{method}: {error}")

    # 作图, 可以选择对多个区间的结果进行对比
    plot_result(
        intervals=intervals,            
        y_true=y_true,                  
        fitting_results=fitting_results,  
        x_experiment=x_experiment,
        x_samples=x_samples,            
        y_samples_noisy=y_samples_noisy,  
        num_experiments=num_experiments  
    )

if __name__ == "__main__":
    main()
